package com.fourth.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fourth.dto.Result;
import com.fourth.entity.AccountStatement;
import com.fourth.entity.User;
import com.fourth.service.IAccountStatementService;
import com.fourth.service.ICardBindingService;
import com.fourth.util.UserHolder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 许桂源
 * @since 2022-08-04
 */
@Controller
@Api(tags = "账目流水")
@RequestMapping("/account-statement")
public class AccountStatementController {
    @Autowired
    private IAccountStatementService accountStatementService;

    @Autowired
    private ICardBindingService cardBindingService;

    /**
     * 根据查询条件查询流水信息
     *
     * @param startDate  开始日期
     * @param endDate    结束日期
     * @param startDate  开始时间
     * @param endDate    结束时间
     * @param selectType 类型
     * @param pageNo     页数
     * @author 许桂源
     */

    @ApiOperation(value = "查询账单流水", notes = "分页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startDate", value = "开始日期", paramType = "String", required = false),
            @ApiImplicitParam(name = "endDate", value = "结束日期", paramType = "String", required = false),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "String", required = false),
            @ApiImplicitParam(name = "endTime", value = "开始时间", paramType = "String", required = false),
            @ApiImplicitParam(name = "selectType", value = "交易类型", paramType = "int", required = false),
            @ApiImplicitParam(name = "pageNo", value = "当前页数", paramType = "int", required = false),
    })
    @PostMapping("/selectFlow")
    @ResponseBody
    public Result getAcState(@RequestParam(value = "startDate", required = false) String startDate,
                             @RequestParam(value = "endDate", required = false) String endDate,
                             @RequestParam(value = "startTime", required = false) String startTime,
                             @RequestParam(value = "endTime", required = false) String endTime,
                             @RequestParam(value = "selectType", defaultValue = "0", required = false) String selectType,
                             @RequestParam(value = "sortType", defaultValue = "0", required = false) String sortType,
                             @RequestParam(value = "pageNo", defaultValue = "1", required = false) String pageNo) {
        // 一、从userHolder获取数据
        final String userPhone = UserHolder.getUser().getUserPhone();

        // 二、分页构造器，条件构造器
        Page<AccountStatement> page = new Page<>(Integer.parseInt(pageNo), 10);
        LambdaQueryWrapper<AccountStatement> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        // 三、填充条件
        // 设置排序
        if (Integer.parseInt(sortType) == 1) {
            // 升序
            lambdaQueryWrapper.orderByAsc(AccountStatement::getTradeTime);
        } else {
            // 降序
            lambdaQueryWrapper.orderByDesc(AccountStatement::getTradeTime);
        }

        // 条件：类型
        if (1 == Integer.parseInt(selectType)) {
            // 如果为充值类型，收款人账户为当前登录用户的电子账户
            lambdaQueryWrapper.eq(AccountStatement::getCollAccount, userPhone)
                    .eq(AccountStatement::getTradeType, selectType);
        } else if (2 == Integer.parseInt(selectType)) {
            // 如果为提现类型，付款人账户为当前登录用户的电子账户
            lambdaQueryWrapper.eq(AccountStatement::getPayAccount, userPhone).
                    eq(AccountStatement::getTradeType, selectType);
        } else if (3 == Integer.parseInt(selectType)) {
            // 如果为转账类型，付款人和收款人都有可能是当前登录用户的电子账户
            lambdaQueryWrapper.and(i -> i
                            .eq(AccountStatement::getCollAccount, userPhone)
                            .or()
                            .eq(AccountStatement::getPayAccount, userPhone))
                    .eq(AccountStatement::getTradeType, selectType);
        } else {
            // 如果为全部类型，只要付款人或收款人账户是当前登录用户的，就都查出来
            lambdaQueryWrapper.and(i -> i
                    .eq(AccountStatement::getCollAccount, userPhone)
                    .or()
                    .eq(AccountStatement::getPayAccount, userPhone));
        }

        // 条件：日期
        String sDate = "";
        String eDate = "";
        String sTime = "";
        String eTime = "";
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 如果什么日期都没填，默认查询当前日期的前一个月
        if ((startDate == null && endDate == null && startTime == null && endTime == null)
                || ("".equals(startDate) && "".equals(endDate) && "".equals(startTime) && "".equals(endTime))) {
            LocalDateTime end = LocalDateTime.now();
            LocalDateTime start = end.minusDays(31);
            start = start.withHour(0).withMinute(0).withSecond(0);
            sTime = "00:00:00";
            eTime = (end.getHour() < 10 ? "0" + end.getHour() : end.getHour()) + ":" +
                    (end.getMinute() < 10 ? "0" + end.getMinute() : end.getMinute()) + ":" +
                    (end.getDayOfMonth() < 10 ? "0" + end.getDayOfMonth() : end.getDayOfMonth());
            sDate = start.format(df).substring(0, 10);
            eDate = end.format(df).substring(0, 10);
        } else {
            // 拼接日期 如果用户没有选择，那就设置默认值
            // 开始日期
            if (startDate == null || "".equals(startDate)) {
                sDate = "1990-01-01";
            } else {
                sDate = startDate;
            }
            // 开始时间
            if (startTime == null || "".equals(startTime)) {
                sTime = "00:00:00";
            } else {
                sTime = startTime + ":00";
            }
            // 结束日期
            if (endDate == null || "".equals(endDate)) {
                eDate = LocalDateTime.now().format(df).substring(0, 10);
            } else {
                eDate = endDate;
            }
            // 结束时间
            if (endTime == null || "".equals(endTime)) {
                eTime = "23:59:59";
            } else {
                eTime = endTime + ":59";
            }
        }

        // 四、先处理部分必须回显数据
        HashMap<String,Object> data = new HashMap<>(12);
        data.put("selectType", selectType);
        data.put("sortType", sortType);
        data.put("startDate", sDate);
        data.put("startTime", sTime.substring(0, 5));
        data.put("endDate", eDate);
        data.put("endTime", eTime.substring(0, 5));

        // 五、过滤失败的流水记录
        lambdaQueryWrapper.eq(AccountStatement::getTradeState,1);

        // 六、判断日期是否正确
        // 拼接日期
        String sDateTime = sDate + " " + sTime;
        String eDateTime = eDate + " " + eTime;
        if (LocalDateTime.parse(sDateTime, df).isAfter(LocalDateTime.parse(eDateTime, df))) {
            // 日期不正确
            data.put("pageNo", 0);
            data.put("pages", 0);
            return Result.fail("日期不正确", data);
        }else {
            // 如果日期正确，查询结果，并返回
            lambdaQueryWrapper.ge(AccountStatement::getTradeTime, sDateTime);
            lambdaQueryWrapper.le(AccountStatement::getTradeTime, eDateTime);
            accountStatementService.page(page, lambdaQueryWrapper);
            data.put("pageNo", page.getCurrent());
            data.put("pages", page.getPages());
        }

        // 七、判断结果
        // 如果查不到数据
        if (page.getRecords().size() == 0) {
            return Result.fail("您该时间段没有流水记录",data);
        }else {
            tranBankId(page);
            data.put("list", page.getRecords());
        }
        return Result.ok("查询成功",data);
    }

    /**
     * 把银行卡账户的显示优化 { 把数据库的银行卡号 转换成 开户行（银行卡号后五位）}
     * @param page 流水数据
     * @author 许桂源
     */
    private void tranBankId(Page<AccountStatement> page){
        List<AccountStatement> oldRecords = page.getRecords();
        List<AccountStatement> newRecords = new ArrayList<>();
        for(AccountStatement oldStatement : oldRecords) {
            AccountStatement newStatement = new AccountStatement();
            // 把copy所有属性
            BeanUtils.copyProperties(oldStatement, newStatement);
            // 如果交易类型为充值，那要修改付款人账户的信息
            if ("1".equals(oldStatement.getTradeType())) {
                // 获取开户行信息
                String pwdName = cardBindingService.getPwdName(oldStatement.getPayAccount());
                String five = oldStatement.getPayAccount().substring(11);
                newStatement.setPayAccount(pwdName+"("+five+")");
                // 如果交易类型为提现，那要修改收款人账户的信息
            }else if("2".equals(oldStatement.getTradeType())) {
                String pwdName = cardBindingService.getPwdName(oldStatement.getCollAccount());
                String five = oldStatement.getCollAccount().substring(11);
                newStatement.setCollAccount(pwdName+"("+five+")");
            }
            newRecords.add(newStatement);
        }
        page.setRecords(newRecords);
    }
}
